﻿using System;
using System.Linq;
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Common
{
    public static class AppExtensions
    {
        public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig =>
            {
                var address = $"http://{configuration.GetValue<string>("Consul:IP")}:{configuration.GetValue<string>("Consul:Port")}";
                consulConfig.Address = new Uri(address);
            }));
            return services;
        }

        public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration, ILoggerFactory loggerFactory, IApplicationLifetime lifetime, IConsulClient consulClient)
        {
            var logger = loggerFactory.CreateLogger("AppExtensions");

            var httpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10),//健康监测
                HTTP = string.Format($"http://{configuration.GetValue<string>("Service:DockerIP")}:{configuration.GetValue<string>("Service:Port")}/api/health"),//心跳检测地址
                Timeout = TimeSpan.FromSeconds(5)
            };
            //注册
            var registration = new AgentServiceRegistration()
            {
                Checks = new[] { httpCheck },
                ID = configuration.GetValue<string>("Service:Name") + "_" + configuration.GetValue<string>("Service:Port"),//服务编号不可重复
                Name = configuration.GetValue<string>("Service:Name"),//服务名称
                Address = configuration.GetValue<string>("Service:IP"),//ip地址
                Port = int.Parse(configuration.GetValue<string>("Service:Port"))//端口

            };

            logger.LogInformation("Registering with Consul");
            consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);

            lifetime.ApplicationStopping.Register(() =>
            {
                logger.LogInformation("Unregistering from Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            });

            return app;
        }
    }
}
